﻿using System.Collections.Generic;
using System.Net.Sockets;

namespace Hsenl.Network {
    public class ErrorCode {
        // 可以尝试重连
        public const int WouldBlock = (int)SocketError.WouldBlock; // 10035 非阻塞 socket 无数据可读, 尝试发起操作但不能立即完成, 建议重连
        public const int InProgress = (int)SocketError.InProgress; // 10036 阻塞操作正在进行, 用于 Staged I/O
        public const int AlreadyInProgress = (int)SocketError.AlreadyInProgress; // 10037 同上, 操作重复发起
        public const int NetworkDown = (int)SocketError.NetworkDown; // 10050 本地网络未运行, 常由 WiFi/网线断, 建议重连
        public const int NetworkUnreachable = (int)SocketError.NetworkUnreachable; // 10051 远端网络不可达, 临时路由问题, 可以在短延时后重连
        public const int NetworkReset = (int)SocketError.NetworkReset; // 10052 网络重置, 本地 TCP 堆栈出现状况, 建议重连
        public const int ConnectionAborted = (int)SocketError.ConnectionAborted; // 10053 本地连接中止(本地关闭)– 多见于"优雅断开", 可能是服务器主动断开了我们, 可以不用重连
        public const int ConnectionReset = (int)SocketError.ConnectionReset; // 10054 对方未正常关闭且强制断开(RST), 建议重连
        public const int NoBufferSpaceAvaiable = (int)SocketError.NoBufferSpaceAvailable; // 10055 本地没有缓冲区资源, 可能临时重试后恢复
        public const int TimeOut = (int)SocketError.TimedOut; // 10060 	请求超时, 网络不稳定, 建议重试后重连
        public const int ConnectionRefused = (int)SocketError.ConnectionRefused; // 10061 目标拒绝连接(未监听), 可重试, 等待服务器恢复
        
        // 不用重连
        public const int AccessDenied = (int)SocketError.AccessDenied; // 10013 权限不足, 操作被禁止(如防火墙、管理员权限), 不可重连
        public const int Fault = (int)SocketError.Fault; // 10014 无效地址, 异常调用, 不可重连
        public const int InvalidArgument = (int)SocketError.InvalidArgument; // 10022 参数错误, 调用逻辑有缺陷, 不可重连
        public const int NotSocket = (int)SocketError.NotSocket; // 10038 使用非 socket 对象, 不可重连
        public const int ProtocolNotSupported = (int)SocketError.ProtocolNotSupported; // 10043 协议不被支持, 逻辑问题, 不可重连
        public const int AddressAlreadyInUse = (int)SocketError.AddressAlreadyInUse; // 10048 地址已被占用, 通常是编程问题或端口冲突, 不应立即重连
        public const int AddressNotAvailable = (int)SocketError.AddressNotAvailable; // 10049 本地地址不可绑定, 编程错误, 不可重连

        // 分水岭, 大于该值的, 都是我们自定义的错误码
        public const int SocketErrorWatershed = 12000;

        public const int Error_MessageReadFailure = 12001;
        public const int Error_MessageWriteFailure = 12002;
        public const int Error_Scripts = 12003; // 代码逻辑错误
        
        public static readonly HashSet<int> fatalSocketErrors = new() {
            (int)SocketError.ConnectionAborted,        // 10053
            (int)SocketError.ConnectionReset,          // 10054
            (int)SocketError.ConnectionRefused,        // 10061
            (int)SocketError.AccessDenied,             // 10013
            (int)SocketError.Fault,                    // 10014
            (int)SocketError.InvalidArgument,          // 10022
            (int)SocketError.NotSocket,                // 10038
            (int)SocketError.ProtocolNotSupported,     // 10043
            (int)SocketError.AddressAlreadyInUse,      // 10048
            (int)SocketError.AddressNotAvailable,      // 10049
        };
        
        public static readonly HashSet<int> retryableErrors = new() {
            (int)SocketError.WouldBlock,               // 10035
            (int)SocketError.InProgress,               // 10036
            (int)SocketError.AlreadyInProgress,        // 10037
            (int)SocketError.NetworkDown,              // 10050
            (int)SocketError.NetworkUnreachable,       // 10051
            (int)SocketError.NetworkReset,             // 10052
            (int)SocketError.NoBufferSpaceAvailable,   // 10055
            (int)SocketError.TimedOut                  // 10060
        };
    }
}